//---------------Sonic CD HW Background Script----------------//
//--------Scripted by Christian Whitehead 'The Taxman'--------//
//-------Unpacked By Rubberduckycooly's Script Unpacker-------//

// Do note, even if the Object's name implies that it's only to be used in HW mode, 
// it always gets used, even in SW mode!

// Aliases
private alias object.value0 : Object.Timer

// These pair of values correspond to X coordinates on the sprite sheet
private alias object.value1 : Object.SpriteL
private alias object.value2 : Object.SpriteR

// These pair of values correspond to Y coodinates on the sprite sheet
// Value4 - SpriteB - is unused
private alias object.value3 : Object.SpriteT
private alias object.value4 : Object.SpriteB

// Oscillating value from 0 to 1023, used to determine the base X position/angle for the background
private alias object.value5 : Object.Oscillation

// The following values were changed between initial release and the current release
// -> The gist of it is, an extra face was added to smooth things out so some other
//    stuff had to be adjusted accordingly too

// How many Faces & Vertexes there are in the Object
// Originally 5 and 20, respectivly, though one update changed it to make it a bit larger instead
private alias 6 : HWBACK_FACECOUNT
private alias 24 : HWBACK_VERTEXCOUNT

// The Offset used when wrapping around from the upper half to lower half Vertexes
// Similarly to the above, this was 15 before this object got updated
private alias 19 : HWBACK_VERTEXOFFSET

// Priority
private alias 1 : PRIORITY_ACTIVE

// Face Buffer Flags
private alias 1 : FACE_FLAG_TEXTURED_2D


event ObjectDraw
	Object.Timer++
	if Object.Timer > 5
		Object.Timer = 0

		object.frame++
		object.frame &= 31

		// As needed, switch the current Palette to another one if needed
		// Palette banks 0 and 1 are inverse of each other, for the background aspects, where
		// red becomes blue and vise-versa
		if object.frame > 15
			SetActivePalette(1, 0, screen.ysize)
		else
			SetActivePalette(0, 0, screen.ysize)
		end if

		// Update the left bounds for the sprite to use
		Object.SpriteL = object.frame
		Object.SpriteL &= 3
		Object.SpriteL <<= 7

		// Each sprite is 128 pixels wide, so just take the left bounds and 
		// add 127 to that to get to the other side
		Object.SpriteR = Object.SpriteL
		Object.SpriteR += 127

		// Also find the top bounds for the sprite to use
		Object.SpriteT = object.frame
		Object.SpriteT &= 15
		Object.SpriteT >>= 2
		Object.SpriteT <<= 7

		// And then similarly, since the sprite is 128 pixels tall,
		// just add 127 to the top bounds to get the bottom bounds
		Object.SpriteB = Object.SpriteT
		Object.SpriteB += 127
	end if

	// Update the Oscillation value, over a range of 1024
	Object.Oscillation++
	Object.Oscillation &= 1023

	// Round down the Oscillation value to range from an angle of 0 through 511
	temp4 = Object.Oscillation
	temp4 >>= 1

	// Get the base sprite Top for the following vertexes to use
	temp1 = Object.SpriteT

	// Starat from Vertex 0, in accordance to what was set to the Faces in ObjectStartup
	arrayPos0 = 0

	// Get the value for the top of the vertexes to follow
	Sin(temp3, temp4)
	temp3 >>= 2
	temp3 -= 128

	// Inverse that value for the bottom of the vertexes to use
	temp4 += 256
	temp4 &= 511

	// And now, update all the vertexes

	// Vertex 0, top left of the first (top left rectangle)
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	// Move the X
	temp3 += 128

	// Vertex 1, top right of the first face (top left rectangle)
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 4, top left of the second face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 5, top right of the second face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 8, top left of the third face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 9, top right of the third face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 12, top left of the fourth face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 13, top right of the foruth face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 16, top left of the fifth face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 17, top right of the fifth face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3

	// The following is for the sixth face, which isn't in the Steam version

	arrayPos0 += 3

	// Vertex 20, top left of the sixth face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 21, top right of the sixth face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3

	// And now, go back as needed to reach the vertexes for the bottom of the faces
	arrayPos0 -= HWBACK_VERTEXOFFSET

	// Move the sprite Y position to now be at the actual bottom of the sprite
	// (This is gonna make it SpriteB, essentially)
	temp1 += 128

	// Get the new, inverted x position
	// -> TempValue4 was inverted above already
	Sin(temp3, temp4)
	temp3 >>= 2
	temp3 -= 128

	// Vertex 2, bottom left of the first face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 3, bottom right of the first face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 6, bottom left of the second face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 7, bottom right of the second face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 10, bottom left of the third face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 11, bottom right of the third face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 14, bottom left of the fourth face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 15, bottom right of the fourth face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0 += 3

	// Vertex 18, bottom left of the fifth face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 19, bottom right of the fifth face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3

	// Extra sixth face, not in the original Steam release

	arrayPos0 += 3

	// Vertex 22, bottom left of the sixth face
	vertexBuffer[arrayPos0].u = Object.SpriteL
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3
	arrayPos0++

	temp3 += 128

	// Vertex 23, bottom right of the sixth face
	vertexBuffer[arrayPos0].u = Object.SpriteR
	vertexBuffer[arrayPos0].v = temp1
	vertexBuffer[arrayPos0].x = temp3

	// And now, set the number of faces and vertexes as needed, so that 
	// the 3d Scene draw function will know how many things to draw
	scene3D.vertexCount = HWBACK_VERTEXCOUNT
	scene3D.faceCount = HWBACK_FACECOUNT

	Draw3DScene()

end event


event ObjectStartup

	// Reset the 3d stuff to be normal
	MatrixTranslateXYZ(MAT_WORLD, 0, 0, 0)
	MatrixTranslateXYZ(MAT_VIEW, 0, 0, 0)

	// Turn the background into the version with only the water, without the wave background
	stage.activeLayer[0] = 3

	LoadSpriteSheet("Special/SSBG1.gif")

	// Place an HW Background Object into the scene, in the last of the Reserved Object Slots
	// This happens, regardless of if the game is in SW or HW render mode, despite the Object's name
	object[31].type = TypeName[HW Background]

	// Make it always active, so that it constantly runs
	object[31].priority = PRIORITY_ACTIVE

	// This is a Background, so make it draw as one of course
	object[31].drawOrder = 0

	// Set initial sprite bounds
	// SpriteB is never referenced much, but set it here anyways
	Object.SpriteL[31] = 0
	Object.SpriteR[31] = 128
	Object.SpriteT[31] = 0
	Object.SpriteB[31] = 128

	arrayPos0 = 0
	temp0 = 0

	// Setup all the Faces for the background
	while arrayPos0 < HWBACK_FACECOUNT

		// Set the Face's corners
		// TempValue0 corresponds to a VertexBuffer ID
		faceBuffer[arrayPos0].a = temp0
		temp0++
		faceBuffer[arrayPos0].b = temp0
		temp0++
		faceBuffer[arrayPos0].c = temp0
		temp0++
		faceBuffer[arrayPos0].d = temp0
		temp0++

		faceBuffer[arrayPos0].flag = FACE_FLAG_TEXTURED_2D

		// Move onto the next Face

		arrayPos0++
	loop

	// Set all Vertexes to have a z value of 1
	// -> This doesn't matter too much really, as 2D Faces don't use the z value
	arrayPos0 = 0
	while arrayPos0 < HWBACK_VERTEXCOUNT
		vertexBuffer[arrayPos0].z = 1
		arrayPos0++
	loop

	// Set all the y positions for all the vertexes

	temp0 = 0
	arrayPos0 = 0
	while temp0 < 128

		// First, set up all the upper vertexes, with a y value of 0

		// First face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Second face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Third face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Fourth face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Fifth face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0

		// Extra Sixth face
		arrayPos0 += 3
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0

		// Loop back to the lower half vertexes
		arrayPos0 -= HWBACK_VERTEXOFFSET

		// Each vertex should be 128 pixels tall
		temp0 += 128

		// First face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Second face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Third face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Fourth face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0 += 3

		// Fifth face
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0

		// Extra, sixth face
		arrayPos0 += 3
		vertexBuffer[arrayPos0].y = temp0
		arrayPos0++
		vertexBuffer[arrayPos0].y = temp0

		arrayPos0++

		// Setup the alternate palette

		// First, copy the current entire palette bank 0 over to palette bank 1
		CopyPalette(0, 0, 1, 0, 255)

		// And now, load 32 colours from the external palette cycle file into 
		// palette bank 1, starting from slot 208
		LoadPalette("SS1H_PalCycle.act", 1, 208, 0, 32)
	loop

end event


// ========================
// Editor Subs
// ========================

event RSDKDraw
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("Special/SSBG1.gif")
	SpriteFrame(-32, -32, 64, 64, 1, 143)


end event
